use serde::{Deserialize, Serialize};
use serde_repr::Serialize_repr;

#[derive(Clone, Debug, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct JsErr {
    app_version: String,
    desc: Desc,
    end_time: String,
    err_type: ErrType,
    keyword: String,
    limit: u32,
    offset: u32,
    openid: String,
    orderby: Orderby,
    start_time: String,
}

impl JsErr {
    pub fn builder() -> JsErrBuilder {
        JsErrBuilder::default()
    }
}

#[derive(Clone, Debug, Serialize_repr, Default)]
#[repr(u8)]
pub enum Desc {
    #[default]
    Yes = 1,
    No = 2,
}

#[derive(Clone, Debug, Serialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum Orderby {
    #[default]
    Uv,
    Pv,
}

#[derive(Clone, Debug, Serialize_repr, Default)]
#[repr(u8)]
pub enum ErrType {
    #[default]
    All = 0,
    Business = 1,
    Plugin = 2,
    System = 3,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsErrRes {
    pub data: JsErrData,
    pub total_count: u32,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsErrData {
    pub error_msg_md5: String,
    pub error_msg: String,
    pub uv: u32,
    pub pv: u32,
    pub error_stack_md5: String,
    pub error_stack: String,
    pub pv_percent: String,
    pub uv_percent: String,
}
#[derive(Clone, Debug, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct JsErrBuilder {
    app_version: String,
    err_type: ErrType,
    start_time: String,
    end_time: String,
    keyword: String,
    openid: String,
    orderby: Orderby,
    desc: Desc,
    offset: u32,
    limit: u32,
}

impl JsErrBuilder {
    pub fn app_version<T>(mut self, app_version: T) -> Self
    where
        T: AsRef<str>,
    {
        self.app_version = app_version.as_ref().to_owned();
        self
    }

    pub fn err_type(mut self, err_type: ErrType) -> Self {
        self.err_type = err_type;
        self
    }

    pub fn start_time<T>(mut self, start: T) -> Self
    where
        T: AsRef<str>,
    {
        self.start_time = start.as_ref().to_owned();
        self
    }

    pub fn end_time<T>(mut self, end: T) -> Self
    where
        T: AsRef<str>,
    {
        self.end_time = end.as_ref().to_owned();
        self
    }

    pub fn keyword<T>(mut self, keyword: T) -> Self
    where
        T: AsRef<str>,
    {
        self.keyword = keyword.as_ref().to_owned();
        self
    }

    pub fn openid<T>(mut self, openid: T) -> Self
    where
        T: AsRef<str>,
    {
        self.openid = openid.as_ref().to_owned();
        self
    }

    pub fn orderby(mut self, orderby: Orderby) -> Self {
        self.orderby = orderby;
        self
    }

    pub fn desc(mut self, desc: Desc) -> Self {
        self.desc = desc;
        self
    }

    pub fn offset(mut self, offset: u32) -> Self {
        self.offset = offset;
        self
    }

    pub fn limit(mut self, limit: u32) -> Self {
        self.limit = limit;
        self
    }

    pub fn build(self) -> JsErr {
        JsErr {
            app_version: self.app_version,
            err_type: self.err_type,
            start_time: self.start_time,
            end_time: self.end_time,
            keyword: self.keyword,
            openid: self.openid,
            orderby: self.orderby,
            desc: self.desc,
            offset: self.offset,
            limit: self.limit,
        }
    }
}
